// BankView.cpp : implementation file
//

#include "stdafx.h"
#include "finance.h"
#include "BankView.h"

#include "financedef.h"
#include "CDataFile.h"

#include "FinanceDoc.h"
#include "FinanceView.h"
#include "SearchView.h"

#include "PageDateRange.h"
#include "PageLoginInfo.h"
#include "DlgSearch.h"
#include "DlgBankUpdate.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


extern CFinanceApp theApp;       


// global var for list view
PTLVCOL		g_BankColumn[BANKBOOK_COLUMNS] = 
							{	// the array order is same as ORDERCOLUMN define
								{ "Bankname",	LVCFMT_CENTER, 100,	1, 2 },	// 0
								{ "Certificate",LVCFMT_LEFT,   180,	1, 0 },	// 1
								{ "Account",	LVCFMT_LEFT,    90,	1, 5 },	// 2
								{ "Bankrate",	LVCFMT_CENTER,  80,	1, 6 },	// 3
								{ "StartDate",	LVCFMT_LEFT,	85,	1, 3 },	// 4
								{ "EndDate",	LVCFMT_LEFT,	85,	1, 3 },	// 5
								{ "Operation",	LVCFMT_LEFT,	85,	1, 0 },	// 5
								{ "Owner",		LVCFMT_CENTER,  95,	1, 1 },	// 6
								{ "Comment",	LVCFMT_LEFT,   260, 1, 4 }	// 7
							};



/////////////////////////////////////////////////////////////////////////////
// CBankView

IMPLEMENT_DYNCREATE(CBankView, CListEditView)

// 
//-------------------------------------------------
CBankView::CBankView()
{
	m_ordercolumn = bank_startdate;
	m_disporder	  = desc;
}

// 
//-------------------------------------------------
CBankView::~CBankView()
{
	if( m_pRecordset != NULL )
	{
		if( m_pRecordset->State )
			m_pRecordset->Close();
		m_pRecordset = NULL;
	}
}


BEGIN_MESSAGE_MAP(CBankView, CListEditView)
	//{{AFX_MSG_MAP(CBankView)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclkList)
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBankView drawing

void CBankView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CBankView diagnostics

#ifdef _DEBUG
void CBankView::AssertValid() const
{
	CListView::AssertValid();
}

void CBankView::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CBankView message handlers


//
// 
//------------------------------------------------------------
void CBankView::OnInitialUpdate() 
{
	CListEditView::OnInitialUpdate();
	
	// Gain a reference to the list control itself
	CListCtrl&		InnerLst = GetListCtrl();
	HDITEM			hditem;
	CFont			m_font;
	INT				i, j;
	
	
	m_imagelist.Create(IDB_HEADER, 9, 1, RGB(255,255,255));
	m_bitmap.LoadBitmap(IDB_BITMAP);
	
	CFlatHeaderCtrl* pFlatHeader = (CFlatHeaderCtrl*)InnerLst.GetHeaderCtrl();
	pFlatHeader->ModifyProperty(FH_PROPERTY_STATICBORDER, TRUE);
	pFlatHeader->SetImageList(&m_imagelist);
	
	
	for( j=0,i=0; i<BANKBOOK_COLUMNS; i++ )
	{
		InnerLst.InsertColumn( j,	g_BankColumn[i].chName, 
			g_BankColumn[i].iFormat, 
			g_BankColumn[i].iWidth );
		if( 1 == g_BankColumn[i].btImgFlag ) 
		{
			hditem.mask = HDI_FORMAT|HDI_IMAGE;	//|HDI_BITMAP;	
			pFlatHeader->GetItem( j, &hditem );
			hditem.fmt |= HDF_IMAGE;			//|HDF_BITMAP;
			hditem.iImage = g_BankColumn[i].btmgIdx;
			hditem.hbm = (HBITMAP)m_bitmap;
			pFlatHeader->SetItem( j, &hditem );
		}
		j++;
	}
	
	m_font.CreateFont(16, 0,0,0,FW_NORMAL, 0,0,0,
		DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial");
	InnerLst.SetFont(&m_font);
	
	// <> Init list ctrl
	InnerLst.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP|LVS_EX_FULLROWSELECT);
	InnerLst.SetBkColor(RGB(252,250,244)); //(RGB(244,242,220)),RGB(247,247,255)
	//InnerLst.SetTextColor(RGB(0,0,255));
	InnerLst.SetTextBkColor(RGB(252,250,244));
	
	HDITEMEX hditemex;
	hditemex.iMinWidth = 21;
	hditemex.iMaxWidth = 200;
	pFlatHeader->SetItemEx(1, &hditemex);
	
	// <> Open RecordSet
	m_pRecordset.CreateInstance(__uuidof(Recordset));
	
	// <> Refresh
	OnRefresh();
}

BOOL CBankView::PreCreateWindow(CREATESTRUCT& cs) 
{
	cs.style |= LVS_REPORT |
				LVS_SINGLESEL |
				LVS_SHOWSELALWAYS; 
				//LVS_OWNERDRAWFIXED;
	
	return CListView::PreCreateWindow(cs);
}

int CBankView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CListEditView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// this code only works for a report-mode list view
	ASSERT( GetStyle() & LVS_REPORT );
	
	// Gain a reference to the list control itself
	CListCtrl&		InnerLst = GetListCtrl();
	CHeaderCtrl*	pHeadCtrl = InnerLst.GetHeaderCtrl();
	
	ASSERT( pHeadCtrl );
	
	VERIFY( m_FlatHeader.SubclassWindow( pHeadCtrl->GetSafeHwnd() ) );
	
	return 0;
}

//
//------------------------------------------------------------
void CBankView::OnRefresh()
{
	// <> open Bankbook by condition
	OpenAccount();
	
	// <> Fill listctrl content
	ShowAccountRec( -1 );
}

//
//------------------------------------------------------------
void CBankView::OpenAccount()
{
	_variant_t	var;
	CString		csSQL;
	CHAR		*chOrder[] = { "ASC", "DESC" };
	CHAR		*chColumn[] = {	// the array order is same as ORDERCOLUMN define
								"Bankname ",
								"Certificate ",
								"Account ",
								"Bankrate ",
								"StartDate ",
								"EndDate ",
								"Operation ",
								"Owner ",
								"Comment ",
							};
	
	
	
	csSQL = "SELECT * FROM Bankbook ORDER BY ";
	csSQL += chColumn[ m_ordercolumn ];
	csSQL += chOrder[ m_disporder ];
	var = csSQL;
	
	if( m_pRecordset->State )
		m_pRecordset->Close();
	
	try
	{
		m_pRecordset->Open( var,   
			theApp.m_pConnection.GetInterfacePtr(),	 // Get the Ptr of connect lib
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
}

//
//------------------------------------------------------------
void CBankView::ShowAccountRec( LONG lAbsIdx )
{
	INT				i, j, iItem;
	_variant_t		var;
	CString			csItem[2];
	CListCtrl&		InnerLst = GetListCtrl();
	
	
	//<> reset state
	InnerLst.DeleteAllItems();
	
	// <> No SQL seg in ini file, only change columns
	if( !m_pRecordset->State )
		return ;
	
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			//AfxMessageBox("Bankbook table is NULL");
			return;
		}
		
		iItem = 0;
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect( g_BankColumn[0].chName );	// Bankname
			if(var.vt != VT_NULL)
				csItem[0] = (LPCSTR)_bstr_t(var);
			else
				csItem[0].Empty();	
			
			InnerLst.InsertItem( iItem, csItem[0], 0 );	
			
			for( j=1,i=1; i<BANKBOOK_COLUMNS; i++ )
			{
				var = m_pRecordset->GetCollect( g_BankColumn[i].chName );	
				if(var.vt != VT_NULL)
					csItem[1] = (LPCSTR)_bstr_t(var);
				else
					csItem[1].Empty();	// comment might be NULL in Table
				
				InnerLst.SetItemText( iItem, j++, csItem[1] );	
			}
			
			var = m_pRecordset->GetCollect("Idx");	// LONG
			if(var.vt != VT_NULL)
				InnerLst.SetItemData( iItem, var.lVal );
			
			
			m_pRecordset->MoveNext();
			iItem++;
		}
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
}

// 
// order is ^ after first click
// ^ is a->z, 2005/01/01 -> 2005/07/01
// pNMListView->iSubItem will not be changed postion after user drag head column
//-------------------------------------------------------------------------------
void CBankView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW*	pNMListView = (NM_LISTVIEW*)pNMHDR;
	BOOL			bSortAscending;
	// map List column order to ORDERCOLUMN define
	BANKORDERCOLUMN	iSQLOrder[BANKBOOK_COLUMNS] ={	// listctrl  
													bank_name,		// 0	
													certificate,	// 1
													bank_account,		
													bank_rate,	
													bank_startdate,	// default
													bank_enddate,	
													bank_operation,
													bank_owner,			
													bank_comment	
												};
	
	
	// If clicked on already sorted column, reverse sort order
	if(pNMListView->iSubItem == m_FlatHeader.GetSortColumn(&bSortAscending))
		bSortAscending = !bSortAscending;
	else
        bSortAscending = TRUE;
	
	m_FlatHeader.SetSortColumn(pNMListView->iSubItem, bSortAscending);
	
	// Do some sort of sorting...
	m_ordercolumn = iSQLOrder[ pNMListView->iSubItem ];
	m_disporder = ( bSortAscending ) ? asc : desc;
	
	// <> Refresh
	OnRefresh();
	
	// Note!! m_iLstCurSel will be -1 after ShowAccountRec(), 
	// even if m_iLstCurSel be assigned a valid value before.
	
	*pResult = 0;
}


// 
// For modify
// Note! must be sync listview and count view
//--------------------------------------------------------------
void CBankView::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CListCtrl&		InnerLst = GetListCtrl();
	POSITION		pos = InnerLst.GetFirstSelectedItemPosition();
	INT				iLstCurSel = InnerLst.GetNextSelectedItem(pos);  // Get item index
	
	
	if( iLstCurSel >= 0 )
	{
		CDlgBankUpdate	dlg;
		DWORD			lAbsidx = 0;
		
		
		lAbsidx = InnerLst.GetItemData( iLstCurSel );
		if( lAbsidx > 0 ) 
		{
			dlg.SetSelIndex( lAbsidx );
			
			if( dlg.DoModal() == IDOK )	
			{
				// <> refresh Search view
				OnRefresh(); 
			}
		}
	}
	*pResult = 0;
}

//
//------------------------------------------------------------
void CBankView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
{
	if( bActivate ) 
	{
		OnRefresh();
	}
	
	CListEditView::OnActivateView(bActivate, pActivateView, pDeactiveView);
}


//
//------------------------------------------------------------
//DEL void CBankView::CloseBankViewRecSet()
//DEL {
//DEL 	if( m_pRecordset != NULL )
//DEL 	{
//DEL 		if( m_pRecordset->State )
//DEL 			m_pRecordset->Close();
//DEL 		m_pRecordset = NULL;
//DEL 	}
//DEL }
